package com.koala.controller;

import com.koala.request.LoginReqDTO;
import com.koala.result.Result;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * @author koala
 * @date 2022/11/25 0:06
 */
@RestController
@AllArgsConstructor
@RequestMapping("/oauth")
@NoArgsConstructor
@Slf4j
public class AuthController {


    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private TokenEndpoint tokenEndpoint;

    @PostMapping("/login")
    public Object postAccessToken(@RequestBody LoginReqDTO login) throws HttpRequestMethodNotSupportedException {
        User clientUser = new User("client", "123456", new ArrayList<>());
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(clientUser, null, new ArrayList<>());
        Map<String, String> map = new HashMap<>();
        map.put("username", login.getUsername());
        map.put("password", login.getPassword());
        map.put("grant_type", "password");
        OAuth2AccessToken accessToken = tokenEndpoint.postAccessToken(token, map).getBody();
        return Result.success(accessToken);
    }

    @PostMapping("/token")
    public Object postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {
        OAuth2AccessToken accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        return Result.success(accessToken);
    }

    @DeleteMapping("/logout")
    public Result logout(String token) {
        OAuth2AccessToken accessToken = tokenStore.readAccessToken(token);
        if (accessToken != null) {
            tokenStore.removeAccessToken(accessToken);
            if (accessToken.getRefreshToken() != null) {
                tokenStore.removeRefreshToken(accessToken.getRefreshToken());
            }
        }
        return Result.success();
    }
}
